
#include "bsp_timer.h"


static list_head_node s_timer_free_list;
static list_head_node s_timer_using_list;


/****************************************************                        
*				bsp_init_timer_sys
* Description:	
* Arguments  :  
* Returns    :  
*****************************************************/
void bsp_init_timer_sys(  p_bsp_timer p_timer_addr, 
						  uint16_t    u_timer_num ){

	uint16_t i =0;

	os_lock();
	bsp_init_list_head_node( &s_timer_free_list, u_timer_num );
	bsp_init_list_head_node( &s_timer_using_list, u_timer_num );
	
	for( i = 0; i < u_timer_num; i ++ ){

		bsp_push_list_unit_head( &s_timer_free_list,&p_timer_addr[i].tr_unit );	
	}
	os_unlock();
}

/****************************************************                        
*				bsp_check_timer
* Description:	
* Arguments  :  
* Returns    :  
*****************************************************/
uint16_t bsp_check_timer( p_bsp_timer p_timer,
						  unsigned char *p_data ){
	
	uint16_t i = 0,u_Ret = TRUE;
	bsp_assert( p_timer );
	bsp_assert( p_data );


	for( i = 0; i < TR_CHECK_LEN; i ++ ){

		if( p_timer->tr_data[i+1] !=  p_data[i+1] ){
			
			u_Ret = FALSE;
			break;
		}
	}
	
	return u_Ret;
}

/****************************************************                        
*				bsp_findDeltimer
* Description:	
* Arguments  :  
* Returns    :  
*****************************************************/
p_bsp_timer bsp_findDeltimer( p_bsp_timer f_timer ){

	p_bsp_timer p_timer = ( p_bsp_timer)0;

	p_list_unit p_uint = ( p_list_unit )0;

	os_lock();
	p_uint = s_timer_using_list.l_head_node.p_next;

	while( p_uint != NULL ){

		p_timer = list_container( p_uint, bsp_timer, tr_unit );
        
        p_uint = p_uint->p_next;
		if( p_timer != ( p_bsp_timer)0 ){

			if( bsp_check_timer( p_timer, f_timer->tr_data )){
				
				bsp_put_timer( p_timer );
				break;
			}
		}
	}
	os_unlock();
	return (( p_bsp_timer)0);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/****************************************************                        
*				bsp_get_timer
* Description:	
* Arguments  :  
* Returns    :  
*****************************************************/
p_bsp_timer bsp_get_timer( bsp_timer_mode   tr_mode,
						   unsigned char   *tr_data,
						   uint16_t			u_max,
						   TIMEROUTFUC     tr_recall ){

	p_list_unit p_uint = ( p_list_unit )0;
	p_bsp_timer p_timer = ( p_bsp_timer )0;

	bsp_assert( tr_data   != NULL );
	bsp_assert( tr_recall != NULL );

	os_lock();

	p_uint = bsp_top_list_unit( &s_timer_free_list );

	if( p_uint != NULL ){

		p_timer = list_container( p_uint, bsp_timer, tr_unit );

		if( p_timer != NULL ){

			memcpy( p_timer->tr_data, tr_data , TR_DATA_LEN );

			p_timer->u_timer_max= u_max;
			p_timer->tr_mode   = tr_mode;
			p_timer->tr_recall = tr_recall;
			p_timer->u_timer_cter= 0;

			bsp_push_list_unit_tail( &s_timer_using_list, p_uint );
		}
	}

	os_unlock();

	return p_timer;
}

/****************************************************                        
*				bsp_put_timer
* Description:	
* Arguments  :  
* Returns    :  
*****************************************************/
void  bsp_put_timer( p_bsp_timer p_timer){

	//bsp_assert( p_timer );
	
	if( p_timer == NULL ){

		return ;
	}

	os_lock();
	
	memset( p_timer->tr_data, 0 , TR_DATA_LEN );
	p_timer->tr_recall = NULL;
	p_timer->u_timer_cter = 0;
	p_timer->u_timer_max  = 0;
	
	if( bsp_delete_list_unit( &s_timer_using_list, &p_timer->tr_unit ) ){
		
		bsp_push_list_unit_head( &s_timer_free_list, &p_timer->tr_unit );
	}
	
	os_unlock();
}
//////////////////////////////////////////////////////////////////////////
/****************************************************                        
*				bsp_triggerTimer
* Description:	
* Arguments  :  
* Returns    :  
*****************************************************/
 void bsp_triggerTimer( void ){
	
	p_list_unit p_uint = NULL; 
	p_bsp_timer p_timer= NULL;

	os_lock();
	p_uint = s_timer_using_list.l_head_node.p_next;

	while( p_uint != NULL ){

		p_timer = list_container( p_uint, bsp_timer, tr_unit );

		if( p_timer != NULL ){

			p_timer->u_timer_cter ++;

			if( p_timer->u_timer_cter >= p_timer->u_timer_max ){

				if( p_timer->tr_recall != NULL ){

					p_timer->tr_recall( p_timer );
				}

				if( p_timer->tr_mode == e_tr_one ){
					
					bsp_put_timer( p_timer );
                    p_uint =  s_timer_using_list.l_head_node.p_next;
				}
				else{

					p_timer->u_timer_cter = 0;
                    p_uint = p_uint->p_next;
				}
			}
            else{
                
                p_uint = p_uint->p_next;
            }
		}

		
	}
	os_unlock();
}



